MAXREFDES82# Code Documentation  V01.00
Maxim Smart Force Sensor
 All Files Functions Variables Macros Groups Pages
LCDConf_stm32f429i_disco_MB1075.c
Go to the documentation of this file.
1 
28 /* Includes ------------------------------------------------------------------*/
29 #include "LCDConf.h"
30 #include "GUI_Private.h"
31 #include "ili9341.h"
32 
52 #undef LCD_SWAP_XY
53 #undef LCD_MIRROR_Y
54 
55 #define LCD_SWAP_XY 1
56 #define LCD_MIRROR_Y 1
57 
58 // MG
59 //#define XSIZE_PHYS 240
60 //#define YSIZE_PHYS 320
61 #define XSIZE_PHYS 320
62 #define YSIZE_PHYS 240
63 
64 #define NUM_BUFFERS 1 // Number of multiple buffers to be used
65 #define NUM_VSCREENS 1 // Number of virtual screens to be used
66 
67 #define BK_COLOR GUI_DARKBLUE
68 
69 #undef GUI_NUM_LAYERS
70 #define GUI_NUM_LAYERS 1
71 
72 #define COLOR_CONVERSION_0 GUICC_M8888I
73 #define DISPLAY_DRIVER_0 GUIDRV_LIN_32
74 
75 
76 #if (GUI_NUM_LAYERS > 1)
77  #define COLOR_CONVERSION_1 GUICC_M8888I
78  #define DISPLAY_DRIVER_1 GUIDRV_LIN_32
79 #endif
80 
81 #ifndef XSIZE_PHYS
82  #error Physical X size of display is not defined!
83 #endif
84 #ifndef YSIZE_PHYS
85  #error Physical Y size of display is not defined!
86 #endif
87 #ifndef NUM_VSCREENS
88  #define NUM_VSCREENS 1
89 #else
90  #if (NUM_VSCREENS <= 0)
91  #error At least one screeen needs to be defined!
92  #endif
93 #endif
94 #if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
95  #error Virtual screens and multiple buffers are not allowed!
96 #endif
97 
98 #define LCD_LAYER0_FRAME_BUFFER ((uint32_t)0xD0400000)
99 #define LCD_LAYER1_FRAME_BUFFER ((uint32_t)0xD0600000)
100 
109 /* Redirect bulk conversion to DMA2D routines */
110 #define DEFINEDMA2D_COLORCONVERSION(PFIX, PIXELFORMAT) \
111 static void Color2IndexBulk_##PFIX##DMA2D(LCD_COLOR * pColor, void * pIndex, U32 NumItems, U8 SizeOfIndex) { \
112  DMA2D_Color2IndexBulk(pColor, pIndex, NumItems, SizeOfIndex, PIXELFORMAT); \
113 } \
114 static void Index2ColorBulk_##PFIX##DMA2D(void * pIndex, LCD_COLOR * pColor, U32 NumItems, U8 SizeOfIndex) { \
115  DMA2D_Index2ColorBulk(pIndex, pColor, NumItems, SizeOfIndex, PIXELFORMAT); \
116 }
117 
126 LTDC_HandleTypeDef hltdc;
127 static DMA2D_HandleTypeDef hdma2d;
128 static LCD_LayerPropTypedef layer_prop[GUI_NUM_LAYERS];
129 
130 static const LCD_API_COLOR_CONV * apColorConvAPI[] =
131 {
133 #if GUI_NUM_LAYERS > 1
134  COLOR_CONVERSION_1,
135 #endif
136 };
137 
138 static U32 aBufferDMA2D [XSIZE_PHYS * sizeof(U32)];
139 static U32 aBuffer_FG [XSIZE_PHYS * sizeof(U32)];
140 static U32 aBuffer_BG [XSIZE_PHYS * sizeof(U32)];
141 
150 static uint32_t LCD_LL_GetPixelformat(uint32_t LayerIndex);
151 static void DMA2D_CopyBuffer(uint32_t LayerIndex, void * pSrc, void * pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLineSrc, uint32_t OffLineDst);
152 static void DMA2D_FillBuffer(uint32_t LayerIndex, void * pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex);
153 static void LCD_LL_Init(void);
154 static void LCD_LL_LayerInit(uint32_t LayerIndex);
155 
156 static void CUSTOM_CopyBuffer(int32_t LayerIndex, int32_t IndexSrc, int32_t IndexDst);
157 static void CUSTOM_CopyRect(int32_t LayerIndex, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t xSize, int32_t ySize);
158 static void CUSTOM_FillRect(int32_t LayerIndex, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t PixelIndex);
159 
160 static void DMA2D_Index2ColorBulk(void * pIndex, LCD_COLOR * pColor, uint32_t NumItems, U8 SizeOfIndex, uint32_t PixelFormat);
161 static void DMA2D_Color2IndexBulk(LCD_COLOR * pColor, void * pIndex, uint32_t NumItems, U8 SizeOfIndex, uint32_t PixelFormat);
162 
163 static void BSP_LCD_DrawBitmap8bpp(int32_t LayerIndex, int32_t x, int32_t y, U8 const * p, int32_t xSize, int32_t ySize, int32_t BytesPerLine);
164 static void BSP_LCD_DrawBitmap16bpp(int32_t LayerIndex, int32_t x, int32_t y, U16 const * p, int32_t xSize, int32_t ySize, int32_t BytesPerLine);
165 static void DMA2D_AlphaBlendingBulk(LCD_COLOR * pColorFG, LCD_COLOR * pColorBG, LCD_COLOR * pColorDst, U32 NumItems);
166 static void DMA2D_AlphaBlending(LCD_COLOR * pColorFG, LCD_COLOR * pColorBG, LCD_COLOR * pColorDst, U32 NumItems);
167 static LCD_PIXELINDEX * _LCD_GetpPalConvTable(const LCD_LOGPALETTE GUI_UNI_PTR * pLogPal, const GUI_BITMAP GUI_UNI_PTR * pBitmap, int LayerIndex);
168 static LCD_COLOR DMA2D_MixColors(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens);
169 static void LCD_MixColorsBulk(U32 * pFG, U32 * pBG, U32 * pDst, unsigned OffFG, unsigned OffBG, unsigned OffDest, unsigned xSize, unsigned ySize, U8 Intens);
170 
171 DEFINEDMA2D_COLORCONVERSION(M8888I, LTDC_PIXEL_FORMAT_ARGB8888)
172 DEFINEDMA2D_COLORCONVERSION(M888, LTDC_PIXEL_FORMAT_ARGB8888)
173 DEFINEDMA2D_COLORCONVERSION(M565, LTDC_PIXEL_FORMAT_RGB565)
174 DEFINEDMA2D_COLORCONVERSION(M1555I, LTDC_PIXEL_FORMAT_ARGB1555)
175 DEFINEDMA2D_COLORCONVERSION(M4444I, LTDC_PIXEL_FORMAT_ARGB4444)
176 
177 static uint32_t GetBufferSize(uint32_t LayerIndex);
186 /*******************************************************************************
187  LTDC and DMA2D BSP Routines
188 *******************************************************************************/
197 void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d)
198 {
199  /* Enable peripheral */
200  __HAL_RCC_DMA2D_CLK_ENABLE();
201 }
202 
210 void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d)
211 {
212  /* Enable DMA2D reset state */
213  __HAL_RCC_DMA2D_FORCE_RESET();
214 
215  /* Release DMA2D from reset state */
216  __HAL_RCC_DMA2D_RELEASE_RESET();
217 }
218 
227 void HAL_LTDC_MspInit(LTDC_HandleTypeDef *hltdc)
228 {
229  GPIO_InitTypeDef GPIO_Init_Structure;
230 
231  /* Enable peripherals and GPIO Clocks */
232  /* Enable the LTDC Clock */
233  __HAL_RCC_LTDC_CLK_ENABLE();
234 
235  /* Enable GPIO Clock */
236  __HAL_RCC_GPIOA_CLK_ENABLE();
237  __HAL_RCC_GPIOB_CLK_ENABLE();
238  __HAL_RCC_GPIOC_CLK_ENABLE();
239  __HAL_RCC_GPIOD_CLK_ENABLE();
240  __HAL_RCC_GPIOF_CLK_ENABLE();
241  __HAL_RCC_GPIOG_CLK_ENABLE();
242 
243  /* Configure peripheral GPIO */
244 
245  /* GPIOs Configuration */
246  /*
247  +------------------------+-----------------------+----------------------------+
248  + LCD pins assignment +
249  +------------------------+-----------------------+----------------------------+
250  | LCD_TFT R2 <-> PC.10 | LCD_TFT G2 <-> PA.06 | LCD_TFT B2 <-> PD.06 |
251  | LCD_TFT R3 <-> PB.00 | LCD_TFT G3 <-> PG.10 | LCD_TFT B3 <-> PG.11 |
252  | LCD_TFT R4 <-> PA.11 | LCD_TFT G4 <-> PB.10 | LCD_TFT B4 <-> PG.12 |
253  | LCD_TFT R5 <-> PA.12 | LCD_TFT G5 <-> PB.11 | LCD_TFT B5 <-> PA.03 |
254  | LCD_TFT R6 <-> PB.01 | LCD_TFT G6 <-> PC.07 | LCD_TFT B6 <-> PB.08 |
255  | LCD_TFT R7 <-> PG.06 | LCD_TFT G7 <-> PD.03 | LCD_TFT B7 <-> PB.09 |
256  -------------------------------------------------------------------------------
257  | LCD_TFT HSYNC <-> PC.06 | LCDTFT VSYNC <-> PA.04 |
258  | LCD_TFT CLK <-> PG.07 | LCD_TFT DE <-> PF.10 |
259  -----------------------------------------------------
260  */
261 
262  /* GPIOA configuration */
263  GPIO_Init_Structure.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_6 |
264  GPIO_PIN_11 | GPIO_PIN_12;
265  GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
266  GPIO_Init_Structure.Pull = GPIO_NOPULL;
267  GPIO_Init_Structure.Speed = GPIO_SPEED_FAST;
268  GPIO_Init_Structure.Alternate= GPIO_AF14_LTDC;
269  HAL_GPIO_Init(GPIOA, &GPIO_Init_Structure);
270 
271  /* GPIOB configuration */
272  GPIO_Init_Structure.Pin = GPIO_PIN_8 | \
273  GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11;
274  HAL_GPIO_Init(GPIOB, &GPIO_Init_Structure);
275 
276  /* GPIOC configuration */
277  GPIO_Init_Structure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_10;
278  HAL_GPIO_Init(GPIOC, &GPIO_Init_Structure);
279 
280  /* GPIOD configuration */
281  GPIO_Init_Structure.Pin = GPIO_PIN_3 | GPIO_PIN_6;
282  HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);
283 
284  /* GPIOF configuration */
285  GPIO_Init_Structure.Pin = GPIO_PIN_10;
286  HAL_GPIO_Init(GPIOF, &GPIO_Init_Structure);
287 
288  /* GPIOG configuration */
289  GPIO_Init_Structure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | \
290  GPIO_PIN_11;
291  HAL_GPIO_Init(GPIOG, &GPIO_Init_Structure);
292 
293  /* GPIOB configuration */
294  GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
295  GPIO_Init_Structure.Alternate= GPIO_AF9_LTDC;
296  HAL_GPIO_Init(GPIOB, &GPIO_Init_Structure);
297 
298  /* GPIOG configuration */
299  GPIO_Init_Structure.Pin = GPIO_PIN_10 | GPIO_PIN_12;
300  HAL_GPIO_Init(GPIOG, &GPIO_Init_Structure);
301 
302  /* Set LTDC Interrupt to the lowest priority */
303  HAL_NVIC_SetPriority(LTDC_IRQn, 0xF, 0);
304 
305  /* Enable LTDC Interrupt */
306  HAL_NVIC_EnableIRQ(LTDC_IRQn);
307 }
308 
316 void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc)
317 {
318  /* Reset peripherals */
319  /* Enable LTDC reset state */
320  __HAL_RCC_LTDC_FORCE_RESET();
321 
322  /* Release LTDC from reset state */
323  __HAL_RCC_LTDC_RELEASE_RESET();
324 }
325 
332 void HAL_LTDC_LineEvenCallback(LTDC_HandleTypeDef *hltdc)
333 {
334  uint32_t Addr;
335  uint32_t layer;
336 
337  for (layer = 0; layer < GUI_NUM_LAYERS; layer++)
338  {
339  if (layer_prop[layer].pending_buffer >= 0)
340  {
341  /* Calculate address of buffer to be used as visible frame buffer */
342  Addr = layer_prop[layer].address + layer_prop[layer].xSize * layer_prop[layer].ySize * layer_prop[layer].pending_buffer * layer_prop[layer].BytesPerPixel;
343  HAL_LTDC_SetAddress(hltdc, Addr, layer);
344 
345  __HAL_LTDC_RELOAD_CONFIG(hltdc);
346 
347  /* Notify STemWin that buffer is used */
348  GUI_MULTIBUF_ConfirmEx(layer, layer_prop[layer].pending_buffer);
349 
350  /* Clear pending buffer flag of layer */
351  layer_prop[layer].pending_buffer = -1;
352  }
353  }
354 
355  HAL_LTDC_ProgramLineEvent(hltdc, 0);
356 }
357 
358 /*******************************************************************************
359  Display configuration
360 *******************************************************************************/
367 void LCD_X_Config(void)
368 {
369  uint32_t i;
370 
371  LCD_LL_Init();
372 
373  /* At first initialize use of multiple buffers on demand */
374 #if (NUM_BUFFERS > 1)
375  for (i = 0; i < GUI_NUM_LAYERS; i++)
376  {
377  GUI_MULTIBUF_ConfigEx(i, NUM_BUFFERS);
378  }
379 #endif
380 
381  /* Set display driver and color conversion for 1st layer */
382  GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER_0, COLOR_CONVERSION_0, 0, 0);
383 
384  /* Set size of 1st layer */
385  if (LCD_GetSwapXYEx(0)) {
386  LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
387  LCD_SetVSizeEx(0, YSIZE_PHYS * NUM_VSCREENS, XSIZE_PHYS);
388  } else {
389  LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
390  LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS * NUM_VSCREENS);
391  }
392 
393 #if (GUI_NUM_LAYERS > 1)
394  /* Set display driver and color conversion for 2nd layer */
395  GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER_1, COLOR_CONVERSION_1, 0, 1);
396  /* Set size of 2nd layer */
397  if (LCD_GetSwapXYEx(1)) {
398  LCD_SetSizeEx (1, YSIZE_PHYS, XSIZE_PHYS);
399  LCD_SetVSizeEx(1, YSIZE_PHYS * NUM_VSCREENS, XSIZE_PHYS);
400  } else {
401  LCD_SetSizeEx (1, XSIZE_PHYS, YSIZE_PHYS);
402  LCD_SetVSizeEx(1, XSIZE_PHYS, YSIZE_PHYS * NUM_VSCREENS);
403  }
404 #endif
405 
406  /*Initialize GUI Layer structure */
407  layer_prop[0].address = LCD_LAYER0_FRAME_BUFFER;
408 #if (GUI_NUM_LAYERS > 1)
409  layer_prop[1].address = LCD_LAYER1_FRAME_BUFFER;
410 #endif
411 
412  /* Setting up VRam address and custom functions for CopyBuffer-, CopyRect- and FillRect operations */
413  for (i = 0; i < GUI_NUM_LAYERS; i++)
414  {
415  layer_prop[i].pColorConvAPI = (LCD_API_COLOR_CONV *)apColorConvAPI[i];
416 
417  layer_prop[i].pending_buffer = -1;
418 
419  /* Set VRAM address */
420  LCD_SetVRAMAddrEx(i, (void *)(layer_prop[i].address));
421 
422  /* Remember color depth for further operations */
423  layer_prop[i].BytesPerPixel = LCD_GetBitsPerPixelEx(i) >> 3;
424 
425  /* Set custom functions for several operations */
426  LCD_SetDevFunc(i, LCD_DEVFUNC_COPYBUFFER, (void(*)(void))CUSTOM_CopyBuffer);
427  LCD_SetDevFunc(i, LCD_DEVFUNC_COPYRECT, (void(*)(void))CUSTOM_CopyRect);
428 
429  /* Filling via DMA2D does only work with 16bpp or more */
430  if (LCD_LL_GetPixelformat(i) <= LTDC_PIXEL_FORMAT_ARGB4444)
431  {
432  LCD_SetDevFunc(i, LCD_DEVFUNC_FILLRECT, (void(*)(void))CUSTOM_FillRect);
433  LCD_SetDevFunc(i, LCD_DEVFUNC_DRAWBMP_8BPP, (void(*)(void))BSP_LCD_DrawBitmap8bpp);
434  }
435 
436  /* Set up drawing routine for 16bpp bitmap using DMA2D */
437  if (LCD_LL_GetPixelformat(i) == LTDC_PIXEL_FORMAT_RGB565) {
438  LCD_SetDevFunc(i, LCD_DEVFUNC_DRAWBMP_16BPP, (void(*)(void))BSP_LCD_DrawBitmap16bpp); /* Set up drawing routine for 16bpp bitmap using DMA2D. Makes only sense with RGB565 */
439  }
440 
441  /* Set up custom color conversion using DMA2D, works only for direct color modes because of missing LUT for DMA2D destination */
442  GUICC_M1555I_SetCustColorConv(Color2IndexBulk_M1555IDMA2D, Index2ColorBulk_M1555IDMA2D); /* Set up custom bulk color conversion using DMA2D for ARGB1555 */
443  GUICC_M565_SetCustColorConv (Color2IndexBulk_M565DMA2D, Index2ColorBulk_M565DMA2D); /* Set up custom bulk color conversion using DMA2D for RGB565 */
444  GUICC_M4444I_SetCustColorConv(Color2IndexBulk_M4444IDMA2D, Index2ColorBulk_M4444IDMA2D); /* Set up custom bulk color conversion using DMA2D for ARGB4444 */
445  GUICC_M888_SetCustColorConv (Color2IndexBulk_M888DMA2D, Index2ColorBulk_M888DMA2D); /* Set up custom bulk color conversion using DMA2D for RGB888 */
446  GUICC_M8888I_SetCustColorConv(Color2IndexBulk_M8888IDMA2D, Index2ColorBulk_M8888IDMA2D); /* Set up custom bulk color conversion using DMA2D for ARGB8888 */
447 
448  /* Set up custom alpha blending function using DMA2D */
449  GUI_SetFuncAlphaBlending(DMA2D_AlphaBlending); /* Set up custom alpha blending function using DMA2D */
450 
451  /* Set up custom function for translating a bitmap palette into index values.
452  Required to load a bitmap palette into DMA2D CLUT in case of a 8bpp indexed bitmap */
453  GUI_SetFuncGetpPalConvTable(_LCD_GetpPalConvTable);
454 
455  /* Set up a custom function for mixing up single colors using DMA2D */
456  GUI_SetFuncMixColors(DMA2D_MixColors);
457 
458  /* Set up a custom function for mixing up arrays of colors using DMA2D */
459  GUI_SetFuncMixColorsBulk(LCD_MixColorsBulk);
460  }
461 }
462 
474 int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData)
475 {
476  int32_t r = 0;
477  uint32_t addr;
478  int32_t xPos, yPos;
479  uint32_t Color;
480 
481  switch (Cmd)
482  {
483  case LCD_X_INITCONTROLLER:
484  LCD_LL_LayerInit(LayerIndex);
485  break;
486 
487  case LCD_X_SETORG:
488  addr = layer_prop[LayerIndex].address + ((LCD_X_SETORG_INFO *)pData)->yPos * layer_prop[LayerIndex].xSize * layer_prop[LayerIndex].BytesPerPixel;
489  HAL_LTDC_SetAddress(&hltdc, addr, LayerIndex);
490  break;
491 
492  case LCD_X_SHOWBUFFER:
493  layer_prop[LayerIndex].pending_buffer = ((LCD_X_SHOWBUFFER_INFO *)pData)->Index;
494  break;
495 
496  case LCD_X_SETLUTENTRY:
497  HAL_LTDC_ConfigCLUT(&hltdc, (uint32_t *)&(((LCD_X_SETLUTENTRY_INFO *)pData)->Color), 1, LayerIndex);
498  break;
499 
500  case LCD_X_ON:
501  __HAL_LTDC_ENABLE(&hltdc);
502  break;
503 
504  case LCD_X_OFF:
505  __HAL_LTDC_DISABLE(&hltdc);
506  break;
507 
508  case LCD_X_SETVIS:
509  if(((LCD_X_SETVIS_INFO *)pData)->OnOff == ENABLE )
510  {
511  __HAL_LTDC_LAYER_ENABLE(&hltdc, LayerIndex);
512  }
513  else
514  {
515  __HAL_LTDC_LAYER_DISABLE(&hltdc, LayerIndex);
516  }
517  __HAL_LTDC_RELOAD_CONFIG(&hltdc);
518  break;
519 
520  case LCD_X_SETPOS:
521  HAL_LTDC_SetWindowPosition(&hltdc,
522  ((LCD_X_SETPOS_INFO *)pData)->xPos,
523  ((LCD_X_SETPOS_INFO *)pData)->yPos,
524  LayerIndex);
525  break;
526 
527  case LCD_X_SETSIZE:
528  GUI_GetLayerPosEx(LayerIndex, (int*)&xPos, (int*)&yPos);
529  layer_prop[LayerIndex].xSize = ((LCD_X_SETSIZE_INFO *)pData)->xSize;
530  layer_prop[LayerIndex].ySize = ((LCD_X_SETSIZE_INFO *)pData)->ySize;
531  HAL_LTDC_SetWindowPosition(&hltdc, xPos, yPos, LayerIndex);
532  break;
533 
534  case LCD_X_SETALPHA:
535  HAL_LTDC_SetAlpha(&hltdc, ((LCD_X_SETALPHA_INFO *)pData)->Alpha, LayerIndex);
536  break;
537 
538  case LCD_X_SETCHROMAMODE:
539  if(((LCD_X_SETCHROMAMODE_INFO *)pData)->ChromaMode != 0)
540  {
541  HAL_LTDC_EnableColorKeying(&hltdc, LayerIndex);
542  }
543  else
544  {
545  HAL_LTDC_DisableColorKeying(&hltdc, LayerIndex);
546  }
547  break;
548 
549  case LCD_X_SETCHROMA:
550 
551  Color = ((((LCD_X_SETCHROMA_INFO *)pData)->ChromaMin & 0xFF0000) >> 16) |\
552  (((LCD_X_SETCHROMA_INFO *)pData)->ChromaMin & 0x00FF00) |\
553  ((((LCD_X_SETCHROMA_INFO *)pData)->ChromaMin & 0x0000FF) << 16);
554 
555  HAL_LTDC_ConfigColorKeying(&hltdc, Color, LayerIndex);
556  break;
557 
558  default:
559  r = -1;
560  }
561  return r;
562 }
563 
564 /*******************************************************************************
565  Static code
566 *******************************************************************************/
572 static void LCD_LL_LayerInit(uint32_t LayerIndex)
573 {
574  uint32_t i;
575  static uint32_t LUT[256];
576  LTDC_LayerCfgTypeDef layer_cfg;
577 
578  if (LayerIndex < GUI_NUM_LAYERS)
579  {
580  /* Layer configuration */
581  layer_cfg.WindowX0 = 0;
582  layer_cfg.WindowX1 = XSIZE_PHYS;
583  layer_cfg.WindowY0 = 0;
584  layer_cfg.WindowY1 = YSIZE_PHYS;
585  layer_cfg.PixelFormat = LCD_LL_GetPixelformat(LayerIndex);
586  layer_cfg.FBStartAdress = layer_prop[LayerIndex].address;
587  layer_cfg.Alpha = 255;
588  layer_cfg.Alpha0 = 0;
589  layer_cfg.Backcolor.Blue = 0;
590  layer_cfg.Backcolor.Green = 0;
591  layer_cfg.Backcolor.Red = 0;
592  layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
593  layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
594  layer_cfg.ImageWidth = XSIZE_PHYS;
595  layer_cfg.ImageHeight = YSIZE_PHYS;
596  HAL_LTDC_ConfigLayer(&hltdc, &layer_cfg, LayerIndex);
597 
598  /* Enable LUT on demand */
599  if (LCD_GetBitsPerPixelEx(LayerIndex) <= 8)
600  {
601  /* Enable usage of LUT for all modes with <= 8bpp*/
602  HAL_LTDC_EnableCLUT(&hltdc, LayerIndex);
603  }
604  else
605  {
606  /* Optional CLUT initialization for AL88 mode (16bpp)*/
607  if (layer_prop[LayerIndex].pColorConvAPI == GUICC_88666I)
608  {
609  HAL_LTDC_EnableCLUT(&hltdc, LayerIndex);
610 
611  for (i = 0; i < 256; i++)
612  {
613  LUT[i] = LCD_API_ColorConv_8666.pfIndex2Color(i);
614  }
615  HAL_LTDC_ConfigCLUT(&hltdc, LUT, 256, LayerIndex);
616  }
617  }
618  }
619 }
620 
626 static void LCD_LL_Init(void)
627 {
628  static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
629  /* DeInit */
630  HAL_LTDC_DeInit(&hltdc);
631 
632  /* Initializaton of ILI9341 component*/
633  ili9341_Init();
634 
635  /* Set LCD Timings */
636 // MG
637 /*
638  hltdc.Init.HorizontalSync = 9;
639  hltdc.Init.VerticalSync = 1;
640  hltdc.Init.AccumulatedHBP = 29;
641  hltdc.Init.AccumulatedVBP = 3;
642  hltdc.Init.AccumulatedActiveH = 323;
643  hltdc.Init.AccumulatedActiveW = 269;
644  hltdc.Init.TotalHeigh = 327;
645  hltdc.Init.TotalWidth = 279;
646 */
647  hltdc.Init.HorizontalSync = 0;
648  hltdc.Init.VerticalSync = 0;
649  hltdc.Init.AccumulatedHBP = 70;
650  hltdc.Init.AccumulatedVBP = 13;
651  hltdc.Init.AccumulatedActiveW = 390;
652  hltdc.Init.AccumulatedActiveH = 253;
653  hltdc.Init.TotalWidth = 408;
654  hltdc.Init.TotalHeigh = 263;
655 
656  /* background value */
657  hltdc.Init.Backcolor.Blue = 0;
658  hltdc.Init.Backcolor.Green = 0;
659  hltdc.Init.Backcolor.Red = 0;
660 
661  /* LCD clock configuration */
662  /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 MHz */
663  /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 MHz */
664  /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 MHz */
665  /* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_8 = 48/8 = 6 MHz */
666  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
667  //PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
668  PeriphClkInitStruct.PLLSAI.PLLSAIN = 230;//102;//95;//96;//97;//98;//99;//101;//110;//90;//100;//150;//128;
669  //PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
670  PeriphClkInitStruct.PLLSAI.PLLSAIR = 2;
671  //PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
672  PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_16;
673  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
674 
675  /* Polarity */
676  hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
677  hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
678  hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
679  hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
680  hltdc.Instance = LTDC;
681 
682  HAL_LTDC_Init(&hltdc);
683  HAL_LTDC_ProgramLineEvent(&hltdc, 0);
684 
685  /* Configure the DMA2D default mode */
686  hdma2d.Init.Mode = DMA2D_R2M;
687  hdma2d.Init.ColorMode = DMA2D_RGB565;
688  hdma2d.Init.OutputOffset = 0x0;
689 
690  hdma2d.Instance = DMA2D;
691 
692  if(HAL_DMA2D_Init(&hdma2d) != HAL_OK)
693  {
694  while (1);
695  }
696 }
697 
703 static uint32_t LCD_LL_GetPixelformat(uint32_t LayerIndex)
704 {
705  const LCD_API_COLOR_CONV * pColorConvAPI;
706 
707  if (LayerIndex >= GUI_NUM_LAYERS)
708  {
709  return 0;
710  }
711  pColorConvAPI = layer_prop[LayerIndex].pColorConvAPI;
712 
713  if (pColorConvAPI == GUICC_M8888I)
714  {
715  return LTDC_PIXEL_FORMAT_ARGB8888;
716  }
717  else if (pColorConvAPI == GUICC_M888)
718  {
719  return LTDC_PIXEL_FORMAT_RGB888;
720  }
721  else if (pColorConvAPI == GUICC_M565)
722  {
723  return LTDC_PIXEL_FORMAT_RGB565;
724  }
725  else if (pColorConvAPI == GUICC_M1555I)
726  {
727  return LTDC_PIXEL_FORMAT_ARGB1555;
728  }
729  else if (pColorConvAPI == GUICC_M4444I)
730  {
731  return LTDC_PIXEL_FORMAT_ARGB4444;
732  }
733  else if (pColorConvAPI == GUICC_8666)
734  {
735  return LTDC_PIXEL_FORMAT_L8;
736  }
737  else if (pColorConvAPI == GUICC_1616I)
738  {
739  return LTDC_PIXEL_FORMAT_AL44;
740  }
741  else if (pColorConvAPI == GUICC_88666I)
742  {
743  return LTDC_PIXEL_FORMAT_AL88;
744  }
745  while (1);
746 }
747 
748 /*********************************************************************
749 *
750 * CopyBuffer
751 */
752 static void DMA2D_CopyBuffer(uint32_t LayerIndex, void * pSrc, void * pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLineSrc, uint32_t OffLineDst)
753 {
754  uint32_t PixelFormat;
755 
756  PixelFormat = LCD_LL_GetPixelformat(LayerIndex);
757  DMA2D->CR = 0x00000000UL | (1 << 9);
758 
759  /* Set up pointers */
760  DMA2D->FGMAR = (uint32_t)pSrc;
761  DMA2D->OMAR = (uint32_t)pDst;
762  DMA2D->FGOR = OffLineSrc;
763  DMA2D->OOR = OffLineDst;
764 
765  /* Set up pixel format */
766  DMA2D->FGPFCCR = PixelFormat;
767 
768  /* Set up size */
769  DMA2D->NLR = (uint32_t)(xSize << 16) | (U16)ySize;
770 
771  DMA2D->CR |= DMA2D_CR_START;
772 
773  /* Wait until transfer is done */
774  while (DMA2D->CR & DMA2D_CR_START)
775  {
776  }
777 }
778 
779 /*********************************************************************
780 *
781 * FillBuffer
782 */
783 static void DMA2D_FillBuffer(uint32_t LayerIndex, void * pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)
784 {
785  uint32_t PixelFormat;
786 
787  PixelFormat = LCD_LL_GetPixelformat(LayerIndex);
788 
789  /* Set up mode */
790  DMA2D->CR = 0x00030000UL | (1 << 9);
791  DMA2D->OCOLR = ColorIndex;
792 
793  /* Set up pointers */
794  DMA2D->OMAR = (uint32_t)pDst;
795 
796  /* Set up offsets */
797  DMA2D->OOR = OffLine;
798 
799  /* Set up pixel format */
800  DMA2D->OPFCCR = PixelFormat;
801 
802  /* Set up size */
803  DMA2D->NLR = (uint32_t)(xSize << 16) | (U16)ySize;
804 
805  DMA2D->CR |= DMA2D_CR_START;
806 
807  /* Wait until transfer is done */
808  while (DMA2D->CR & DMA2D_CR_START)
809  {
810  }
811 }
812 
813 
814 /*********************************************************************
815 *
816 * GetBufferSize
817 */
818 static uint32_t GetBufferSize(uint32_t LayerIndex)
819 {
820  uint32_t BufferSize;
821 
822  BufferSize = layer_prop[LayerIndex].xSize * layer_prop[LayerIndex].ySize * layer_prop[LayerIndex].BytesPerPixel;
823  return BufferSize;
824 }
825 
826 /*********************************************************************
827 *
828 * CUSTOM_CopyBuffer
829 */
830 static void CUSTOM_CopyBuffer(int32_t LayerIndex, int32_t IndexSrc, int32_t IndexDst) {
831  uint32_t BufferSize, AddrSrc, AddrDst;
832 
833  BufferSize = GetBufferSize(LayerIndex);
834  AddrSrc = layer_prop[LayerIndex].address + BufferSize * IndexSrc;
835  AddrDst = layer_prop[LayerIndex].address + BufferSize * IndexDst;
836  DMA2D_CopyBuffer(LayerIndex, (void *)AddrSrc, (void *)AddrDst, layer_prop[LayerIndex].xSize, layer_prop[LayerIndex].ySize, 0, 0);
837  layer_prop[LayerIndex].buffer_index = IndexDst;
838 }
839 
840 /*********************************************************************
841 *
842 * CUSTOM_CopyRect
843 */
855 static void CUSTOM_CopyRect(int32_t LayerIndex, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t xSize, int32_t ySize)
856 {
857  U32 AddrSrc, AddrDst;
858 
859  AddrSrc = layer_prop[LayerIndex].address + (y0 * layer_prop[LayerIndex].xSize + x0) * layer_prop[LayerIndex].BytesPerPixel;
860  AddrDst = layer_prop[LayerIndex].address + (y1 * layer_prop[LayerIndex].xSize + x1) * layer_prop[LayerIndex].BytesPerPixel;
861  DMA2D_CopyBuffer(LayerIndex, (void *)AddrSrc, (void *)AddrDst, xSize, ySize, layer_prop[LayerIndex].xSize - xSize, layer_prop[LayerIndex].xSize - xSize);
862 }
863 
864 /*********************************************************************
865 *
866 * CUSTOM_FillRect
867 */
868 static void CUSTOM_FillRect(int32_t LayerIndex, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t PixelIndex)
869 {
870  uint32_t BufferSize, AddrDst;
871  int32_t xSize, ySize;
872 
873  if (GUI_GetDrawMode() == GUI_DM_XOR)
874  {
875  LCD_SetDevFunc(LayerIndex, LCD_DEVFUNC_FILLRECT, NULL);
876  LCD_FillRect(x0, y0, x1, y1);
877  LCD_SetDevFunc(LayerIndex, LCD_DEVFUNC_FILLRECT, (void(*)(void))CUSTOM_FillRect);
878  }
879  else
880  {
881  xSize = x1 - x0 + 1;
882  ySize = y1 - y0 + 1;
883  BufferSize = GetBufferSize(LayerIndex);
884  AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y0 * layer_prop[LayerIndex].xSize + x0) * layer_prop[LayerIndex].BytesPerPixel;
885  DMA2D_FillBuffer(LayerIndex, (void *)AddrDst, xSize, ySize, layer_prop[LayerIndex].xSize - xSize, PixelIndex);
886  }
887 }
888 
895 static void DMA2D_LoadLUT(LCD_COLOR * pColor, uint32_t NumItems)
896 {
897  DMA2D->FGCMAR = (uint32_t)pColor;
898 
899  /* Foreground PFC Control Register */
900  DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_RGB888 /* Pixel format */
901  | ((NumItems - 1) & 0xFF) << 8; /* Number of items to load */
902  DMA2D->FGPFCCR |= (1 << 5); /* Start loading */
903 }
904 
912 static void InvertAlpha_SwapRB(LCD_COLOR * pColorSrc, LCD_COLOR * pColorDst, uint32_t NumItems)
913 {
914  uint32_t Color;
915  do
916  {
917  Color = *pColorSrc++;
918  *pColorDst++ = ((Color & 0x000000FF) << 16) /* Swap red <-> blue */
919  | (Color & 0x0000FF00) /* Green */
920  | ((Color & 0x00FF0000) >> 16) /* Swap red <-> blue */
921  | ((Color & 0xFF000000) ^ 0xFF000000); /* Invert alpha */
922  } while (--NumItems);
923 }
924 
933 static void InvertAlpha(LCD_COLOR * pColorSrc, LCD_COLOR * pColorDst, uint32_t NumItems)
934 {
935  uint32_t Color;
936 
937  do
938  {
939  Color = *pColorSrc++;
940  *pColorDst++ = Color ^ 0xFF000000; /* Invert alpha */
941  } while (--NumItems);
942 }
943 
952 static void DMA2D_AlphaBlendingBulk(LCD_COLOR * pColorFG, LCD_COLOR * pColorBG, LCD_COLOR * pColorDst, U32 NumItems)
953 {
954  /* Set up mode */
955  DMA2D->CR = 0x00020000UL | (1 << 9); /* Control Register (Memory to memory with blending of FG and BG and TCIE) */
956 
957  /* Set up pointers */
958  DMA2D->FGMAR = (uint32_t)pColorFG; /* Foreground Memory Address Register */
959  DMA2D->BGMAR = (uint32_t)pColorBG; /* Background Memory Address Register */
960  DMA2D->OMAR = (uint32_t)pColorDst; /* Output Memory Address Register (Destination address) */
961 
962  /* Set up offsets */
963  DMA2D->FGOR = 0; /* Foreground Offset Register */
964  DMA2D->BGOR = 0; /* Background Offset Register */
965  DMA2D->OOR = 0; /* Output Offset Register */
966 
967  /* Set up pixel format */
968  DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888; /* Foreground PFC Control Register (Defines the FG pixel format) */
969  DMA2D->BGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888; /* Background PFC Control Register (Defines the BG pixel format) */
970  DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_ARGB8888; /* Output PFC Control Register (Defines the output pixel format) */
971 
972  /* Set up size */
973  DMA2D->NLR = (uint32_t)(NumItems << 16) | 1; /* Number of Line Register (Size configuration of area to be transfered) */
974 
975  /* Execute operation */
976 
977  DMA2D->CR |= DMA2D_CR_START;
978 
979  while (DMA2D->CR & DMA2D_CR_START)
980  {
981  }
982 }
983 
984 #if defined (__GNUC__)
985  #pragma GCC optimize ("O0")
986 #endif
987 
996 static LCD_COLOR DMA2D_MixColors(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens)
997 {
998  uint32_t ColorFG, ColorBG, ColorDst;
999 
1000  if ((BkColor & 0xFF000000) == 0xFF000000)
1001  {
1002  return Color;
1003  }
1004  ColorFG = Color ^ 0xFF000000;
1005  ColorBG = BkColor ^ 0xFF000000;
1006 
1007  /* Set up mode */
1008  DMA2D->CR = 0x00020000UL | (1 << 9); /* Control Register (Memory to memory with blending of FG and BG and TCIE) */
1009 
1010  /* Set up pointers */
1011  DMA2D->FGMAR = (uint32_t)&ColorFG; /* Foreground Memory Address Register */
1012  DMA2D->BGMAR = (uint32_t)&ColorBG; /* Background Memory Address Register */
1013  DMA2D->OMAR = (uint32_t)&ColorDst; /* Output Memory Address Register (Destination address) */
1014 
1015  /* Set up pixel format */
1016  DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888
1017  | (1UL << 16)
1018  | ((uint32_t)Intens << 24);
1019  DMA2D->BGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888
1020  | (0UL << 16)
1021  | ((uint32_t)(255 - Intens) << 24);
1022  DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_ARGB8888;
1023 
1024  /* Set up size */
1025  DMA2D->NLR = (uint32_t)(1 << 16) | 1; /* Number of Line Register (Size configuration of area to be transfered) */
1026 
1027  /* Execute operation */
1028  DMA2D->CR |= DMA2D_CR_START; /* Control Register (Start operation) */
1029 
1030  /* Wait until transfer is done */
1031  while (DMA2D->CR & DMA2D_CR_START)
1032  {
1033  }
1034 
1035  return (ColorDst ^ 0xFF000000);
1036 }
1037 
1047 static void DMA2D_ConvertColor(void * pSrc, void * pDst, uint32_t PixelFormatSrc, uint32_t PixelFormatDst, uint32_t NumItems)
1048 {
1049  /* Set up mode */
1050 
1051  DMA2D->CR = 0x00010000UL | (1 << 9); /* Control Register (Memory to memory with pixel format conversion and TCIE) */
1052 
1053  /* Set up pointers */
1054  DMA2D->FGMAR = (uint32_t)pSrc; /* Foreground Memory Address Register (Source address) */
1055  DMA2D->OMAR = (uint32_t)pDst; /* Output Memory Address Register (Destination address) */
1056 
1057  /* Set up offsets */
1058  DMA2D->FGOR = 0; /* Foreground Offset Register (Source line offset) */
1059  DMA2D->OOR = 0; /* Output Offset Register (Destination line offset) */
1060 
1061  /* Set up pixel format */
1062  DMA2D->FGPFCCR = PixelFormatSrc; /* Foreground PFC Control Register (Defines the input pixel format) */
1063  DMA2D->OPFCCR = PixelFormatDst; /* Output PFC Control Register (Defines the output pixel format) */
1064 
1065  /* Set up size */
1066  DMA2D->NLR = (uint32_t)(NumItems << 16) | 1; /* Number of Line Register (Size configuration of area to be transfered) */
1067 
1068  /* Execute operation */
1069  DMA2D->CR |= DMA2D_CR_START;
1070 
1071  while (DMA2D->CR & DMA2D_CR_START)
1072  {
1073  }
1074 }
1075 
1086 static LCD_PIXELINDEX * _LCD_GetpPalConvTable(const LCD_LOGPALETTE GUI_UNI_PTR * pLogPal, const GUI_BITMAP GUI_UNI_PTR * pBitmap, int LayerIndex)
1087 {
1088  void (* pFunc)(void);
1089  int32_t DoDefault = 0;
1090 
1091  /* Check if we have a non transparent device independent bitmap */
1092  if (pBitmap->BitsPerPixel == 8)
1093  {
1094  pFunc = LCD_GetDevFunc(LayerIndex, LCD_DEVFUNC_DRAWBMP_8BPP);
1095  if (pFunc)
1096  {
1097  if (pBitmap->pPal)
1098  {
1099  if (pBitmap->pPal->HasTrans)
1100  {
1101  DoDefault = 1;
1102  }
1103  }
1104  else
1105  {
1106  DoDefault = 1;
1107  }
1108  }
1109  else
1110  {
1111  DoDefault = 1;
1112  }
1113  }
1114  else
1115  {
1116  DoDefault = 1;
1117  }
1118 
1119  /* Default palette management for other cases */
1120  if (DoDefault)
1121  {
1122 
1123  /* Return a pointer to the index values to be used by the controller */
1124  return LCD_GetpPalConvTable(pLogPal);
1125  }
1126 
1127  /* Convert palette colors from ARGB to ABGR */
1128  InvertAlpha_SwapRB((U32 *)pLogPal->pPalEntries, aBufferDMA2D, pLogPal->NumEntries);
1129 
1130  /* Load LUT using DMA2D */
1131  DMA2D_LoadLUT(aBufferDMA2D, pLogPal->NumEntries);
1132 
1133  /* Return something not NULL */
1134  return aBufferDMA2D;
1135 }
1136 
1146 static void DMA2D_MixColorsBulk(LCD_COLOR * pColorFG, LCD_COLOR * pColorBG, LCD_COLOR * pColorDst, U8 Intens, uint32_t NumItems)
1147 {
1148  /* Set up mode */
1149  DMA2D->CR = 0x00020000UL | (1 << 9); /* Control Register (Memory to memory with blending of FG and BG and TCIE) */
1150 
1151  /* Set up pointers */
1152  DMA2D->FGMAR = (uint32_t)pColorFG; /* Foreground Memory Address Register */
1153  DMA2D->BGMAR = (uint32_t)pColorBG; /* Background Memory Address Register */
1154  DMA2D->OMAR = (uint32_t)pColorDst; /* Output Memory Address Register (Destination address) */
1155 
1156  /* Set up pixel format */
1157  DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888
1158  | (1UL << 16)
1159  | ((uint32_t)Intens << 24);
1160  DMA2D->BGPFCCR = LTDC_PIXEL_FORMAT_ARGB8888
1161  | (0UL << 16)
1162  | ((uint32_t)(255 - Intens) << 24);
1163  DMA2D->OPFCCR = LTDC_PIXEL_FORMAT_ARGB8888;
1164 
1165  /* Set up size */
1166  DMA2D->NLR = (uint32_t)(NumItems << 16) | 1; /* Number of Line Register (Size configuration of area to be transfered) */
1167 
1168  /* Execute operation */
1169  DMA2D->CR |= DMA2D_CR_START;
1170 
1171  while (DMA2D->CR & DMA2D_CR_START)
1172  {
1173  }
1174 }
1175 
1184 static void DMA2D_AlphaBlending(LCD_COLOR * pColorFG, LCD_COLOR * pColorBG, LCD_COLOR * pColorDst, U32 NumItems)
1185 {
1186  /* Invert alpha values */
1187  InvertAlpha(pColorFG, aBuffer_FG, NumItems);
1188  InvertAlpha(pColorBG, aBuffer_BG, NumItems);
1189 
1190  /* Use DMA2D for mixing */
1191  DMA2D_AlphaBlendingBulk(aBuffer_FG, aBuffer_BG, aBufferDMA2D, NumItems);
1192 
1193  /* Invert alpha values */
1194  InvertAlpha(aBufferDMA2D, pColorDst, NumItems);
1195 }
1196 
1209 static void DMA2D_Index2ColorBulk(void * pIndex, LCD_COLOR * pColor, uint32_t NumItems, U8 SizeOfIndex, uint32_t PixelFormat)
1210 {
1211  /* Use DMA2D for the conversion */
1212  DMA2D_ConvertColor(pIndex, aBufferDMA2D, PixelFormat, LTDC_PIXEL_FORMAT_ARGB8888, NumItems);
1213 
1214  /* Convert colors from ARGB to ABGR and invert alpha values */
1215  InvertAlpha_SwapRB(aBufferDMA2D, pColor, NumItems);
1216 }
1217 
1230 static void DMA2D_Color2IndexBulk(LCD_COLOR * pColor, void * pIndex, uint32_t NumItems, U8 SizeOfIndex, uint32_t PixelFormat)
1231 {
1232  /* Convert colors from ABGR to ARGB and invert alpha values */
1233  InvertAlpha_SwapRB(pColor, aBufferDMA2D, NumItems);
1234 
1235  /* Use DMA2D for the conversion */
1236  DMA2D_ConvertColor(aBufferDMA2D, pIndex, LTDC_PIXEL_FORMAT_ARGB8888, PixelFormat, NumItems);
1237 }
1238 
1252 static void LCD_MixColorsBulk(U32 * pFG, U32 * pBG, U32 * pDst, unsigned OffFG, unsigned OffBG, unsigned OffDest, unsigned xSize, unsigned ySize, U8 Intens)
1253 {
1254  int32_t y;
1255 
1256  GUI_USE_PARA(OffFG);
1257  GUI_USE_PARA(OffDest);
1258  for (y = 0; y < ySize; y++)
1259  {
1260  /* Invert alpha values */
1261  InvertAlpha(pFG, aBuffer_FG, xSize);
1262  InvertAlpha(pBG, aBuffer_BG, xSize);
1263 
1264  DMA2D_MixColorsBulk(aBuffer_FG, aBuffer_BG, aBufferDMA2D, Intens, xSize);
1265 
1266  InvertAlpha(aBufferDMA2D, pDst, xSize);
1267  pFG += xSize + OffFG;
1268  pBG += xSize + OffBG;
1269  pDst += xSize + OffDest;
1270  }
1271 }
1272 
1284 static void DMA2D_DrawBitmapL8(void * pSrc, void * pDst, uint32_t OffSrc, uint32_t OffDst, uint32_t PixelFormatDst, uint32_t xSize, uint32_t ySize)
1285 {
1286  /* Set up mode */
1287  DMA2D->CR = 0x00010000UL | (1 << 9); /* Control Register (Memory to memory with pixel format conversion and TCIE) */
1288 
1289  /* Set up pointers */
1290  DMA2D->FGMAR = (uint32_t)pSrc; /* Foreground Memory Address Register (Source address) */
1291  DMA2D->OMAR = (uint32_t)pDst; /* Output Memory Address Register (Destination address) */
1292 
1293  /* Set up offsets */
1294  DMA2D->FGOR = OffSrc; /* Foreground Offset Register (Source line offset) */
1295  DMA2D->OOR = OffDst; /* Output Offset Register (Destination line offset) */
1296 
1297  /* Set up pixel format */
1298  DMA2D->FGPFCCR = LTDC_PIXEL_FORMAT_L8; /* Foreground PFC Control Register (Defines the input pixel format) */
1299  DMA2D->OPFCCR = PixelFormatDst; /* Output PFC Control Register (Defines the output pixel format) */
1300 
1301  /* Set up size */
1302  DMA2D->NLR = (uint32_t)(xSize << 16) | ySize; /* Number of Line Register (Size configuration of area to be transfered) */
1303 
1304  /* Execute operation */
1305  DMA2D->CR |= DMA2D_CR_START; /* Start operation */
1306 
1307  /* Wait until transfer is done */
1308  while (DMA2D->CR & DMA2D_CR_START)
1309  {
1310  }
1311 }
1312 
1324 static void BSP_LCD_DrawBitmap16bpp(int32_t LayerIndex, int32_t x, int32_t y, U16 const * p, int32_t xSize, int32_t ySize, int32_t BytesPerLine)
1325 {
1326  uint32_t BufferSize, AddrDst;
1327  int32_t OffLineSrc, OffLineDst;
1328 
1329  BufferSize = GetBufferSize(LayerIndex);
1330  AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
1331  OffLineSrc = (BytesPerLine / 2) - xSize;
1332  OffLineDst = layer_prop[LayerIndex].xSize - xSize;
1333  DMA2D_CopyBuffer(LayerIndex, (void *)p, (void *)AddrDst, xSize, ySize, OffLineSrc, OffLineDst);
1334 }
1335 
1347 static void BSP_LCD_DrawBitmap8bpp(int32_t LayerIndex, int32_t x, int32_t y, U8 const * p, int32_t xSize, int32_t ySize, int32_t BytesPerLine)
1348 {
1349  uint32_t BufferSize, AddrDst;
1350  int32_t OffLineSrc, OffLineDst;
1351  uint32_t PixelFormat;
1352 
1353  BufferSize = GetBufferSize(LayerIndex);
1354  AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
1355  OffLineSrc = BytesPerLine - xSize;
1356  OffLineDst = layer_prop[LayerIndex].xSize - xSize;
1357  PixelFormat = LCD_LL_GetPixelformat(LayerIndex);
1358  DMA2D_DrawBitmapL8((void *)p, (void *)AddrDst, OffLineSrc, OffLineDst, PixelFormat, xSize, ySize);
1359 }
1360 /*************************** End of file ****************************/